<template>
  <label class="label78">
    <input type="checkbox" class="checkbox78" :checked="!isDark" @click="handleToggle" />
    <div class="status78"></div>
  </label>
</template>

<script setup lang="ts">
import { useDark, useToggle } from '@vueuse/core';

const isDark = useDark();
const toggleDark = useToggle(isDark);
const handleToggle = (e: MouseEvent) => {
  const transition = document.startViewTransition(() => {
    // 在 startViewTransition 中修改 DOM 状态产生动画
    toggleDark();
  });
  // 在 transition.ready 的 Promise 完成后，执行自定义动画
  transition.ready.then(() => {
    // 由于我们要从鼠标点击的位置开始做动画，所以我们需要先获取到鼠标的位置
    const { clientX, clientY } = e;

    // 计算半径，以鼠标点击的位置为圆心，到四个角的距离中最大的那个作为半径
    const radius = Math.hypot(
      Math.max(clientX, innerWidth - clientX),
      Math.max(clientY, innerHeight - clientY),
    );

    const clipPath = [
      `circle(0% at ${clientX}px ${clientY}px)`,
      `circle(${radius}px at ${clientX}px ${clientY}px)`,
    ];

    // 自定义动画
    document.documentElement.animate(
      {
        clipPath: isDark.value ? clipPath.reverse() : clipPath,
      },
      {
        duration: 300,
        // pseudoElement: '::view-transition-new(root)',
        pseudoElement: isDark.value ? '::view-transition-old(root)' : '::view-transition-new(root)',
      },
    );
  });
};
</script>

<style lang="scss" scoped>
.label78 {
  position: relative;
  cursor: pointer;
  overflow: hidden;
}
.checkbox78 {
  width: 90px;
  height: 40px;
  background-color: #000000;
  border-radius: 20px;
  margin: 0;
  cursor: pointer;
  box-sizing: border-box;
  transition: all 0.4s linear;
  appearance: none;
  -webkit-appearance: none;
}
.status78 {
  width: 16px;
  height: 16px;
  background-color: transparent;
  box-shadow: inset -6px -4px 0 yellow;
  border-radius: 50%;
  position: absolute;
  right: 17px;
  top: 12px;
  transition: all 0.4s linear;
  display: flex;
  align-items: center;
  justify-content: center;
}
.status78:after {
  content: '深色';
  font-size: 14px;
  font-weight: bold;
  color: #ffffff;
  letter-spacing: 3px;
  line-height: 1;
  position: absolute;
  left: -38px;
  top: 1px;
}
.checkbox78:checked {
  background-color: #ebebeb;
}
.checkbox78:checked + .status78 {
  width: 16px;
  height: 16px;
  box-shadow: inset -16px -16px 0 red;
  right: 17px;
}
.checkbox78:checked + .status78:after {
  content: '浅色';
  color: #000000;
}
</style>
